﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using blackhouse.BlackApart.Business.Reservations;
using blackhouse.BlackApart.Data;

namespace blackhouse.BlackApart.Business.ApartmentServices {
    public class DaAdditionalService : IAdditionalService {

        #region Fields

        private ImpAdditionalService instance;
        private IAdditionalServiceDataAccess data;

        #endregion

        #region Properties

        public int ServiceId { get { return this.instance.ServiceId; } private set { this.instance.ServiceId = value; } }
        public string ServiceKey { get { return this.instance.ServiceKey; } private set { this.instance.ServiceKey = value; } }
        public string ServiceName { get { return this.instance.ServiceName; } private set { this.instance.ServiceName = value; } }
        public string Description { get { return this.instance.Description; } private set { this.instance.Description = value; } }
        public string ApartmentDescription { get { return this.instance.ApartmentDescription; } private set { this.instance.ApartmentDescription = value; } }
        public ServiceFor ServiceFor { get { return this.instance.ServiceFor; } private set { this.instance.ServiceFor = value; } }
        public ServiceTime ServiceTime { get { return this.instance.ServiceTime; } private set { this.instance.ServiceTime = value; } }
        public double UnitPrice { get { return this.instance.UnitPrice; } set { this.instance.UnitPrice = value; } }
        public double PriceOnDemand { get { return this.instance.PriceOnDemand; } set { this.instance.PriceOnDemand = value; } }
        public string ReviewTitle { get { return this.instance.ReviewTitle; } set { this.instance.ReviewTitle = value; } }
        public int DefaultQuantity { get { return this.instance.DefaultQuantity; } }
        public bool RemoveQuantityLimit { get { return this.instance.RemoveQuantityLimit; } }

        #endregion

        #region Constructors

        public DaAdditionalService(IAdditionalServiceDataAccess dataAccess) {
            this.data = dataAccess;
            this.instance = new ImpAdditionalService();
        }

        private DaAdditionalService(IAdditionalServiceDataAccess dataAccess, AdditionalServiceData data) {
            this.data = dataAccess;
            this.instance = this.Convert(data);
            if (this.instance == null) this.instance = new ImpAdditionalService();
        }

        #endregion

        #region Methods

        private ImpAdditionalService Convert(AdditionalServiceData data) {
            ImpAdditionalService instance = new ImpAdditionalService();
            instance.ServiceId = data.ServiceId;
            instance.ServiceKey = data.ServiceKey;
            instance.ServiceName = data.ServiceName;
            instance.Description = data.Description;
            instance.ApartmentDescription = data.ApartmentDescription;

            ServiceFor sf = ServiceFor.None;
            if (data.ServiceDate) sf = sf | ServiceFor.Day;
            if (data.ServiceRoom) sf = sf | ServiceFor.Room;
            if (data.ServiceQuantity) sf = sf | ServiceFor.Quantity;
            instance.ServiceFor = sf;
            if (!string.IsNullOrEmpty(data.ServiceTime) && Enum.IsDefined(typeof(ServiceTime), data.ServiceTime))
                instance.ServiceTime = (ServiceTime)Enum.Parse(typeof(ServiceTime), data.ServiceTime);
            instance.UnitPrice = data.UnitPrice;
            instance.PriceOnDemand = data.PriceOnDemand;
            instance.ReviewTitle = data.ReviewTitle;
            instance.DefaultQuantity = data.DefaultQuantity;
            instance.RemoveQuantityLimit = data.RemoveQuantityLimit;
            return instance;
        }

        public IAdditionalService[] GetServices(int apartmentGroupId) {
            AdditionalServiceData[] data = this.data.GetAvalibleServices(apartmentGroupId, CultureInfo.CurrentCulture.Name);
            return data.Select(d => new DaAdditionalService(this.data, d)).ToArray();
        }

        public IAdditionalService FindService(int apartmentGroupId, string serviceKey) {
            return this.GetServices(apartmentGroupId).FirstOrDefault(s => s.ServiceKey == serviceKey);
        }

        public IAdditionalService[] GetServicesForReservation(int forReservationId) {
            AdditionalServiceData[] data = this.data.GetAvalibleServicesForReservation(forReservationId, CultureInfo.CurrentCulture.Name);
            return data.Select(d => new DaAdditionalService(this.data, d)).ToArray();
        }

        public ReservationAdditionalService AddToReservation(IWebReservation reservation) {
            return this.GetOrderFromReservation(reservation);
        }

        public ReservationAdditionalService GetOrderFromReservation(IWebReservation reservation) {
            return new DaReservationAdditionalService(reservation, this, this.data);
        }

        #endregion

    }
}
